iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0

在處理動態資料時,經常需要與後端伺服器進行溝通,這通常透過 HTTP 請求來完成。今天要介紹如何在 Angular 中實現這一功能。

HttpClient

HttpClient 是 Angular 提供的一個服務,用於發送 HTTP 請求並處理回應。它基於 RxJS,這意味著它的許多方法都會回傳 Observable ,所以就可以透過上一章接觸到的 RxJS 來處理非同步資料流,使用 subscribe 來訂閱,並根據回傳的結果來做相對應的處理。

注入 HttpClient

在元件中使用 HttpClient 之前,需要設定 provide ,才能在元件中注入,可以在元件中設定,但較常見的是在應用程式啟動時設定,就可以在所有元件中使用。

  • provideHttpClient 用來設定 HttpClient 服務。
bootstrapApplication(AppComponent, {
	  providers: [ provideHttpClient() ]
})

設定完後,就可以在元件中注入 HttpClient 了。

// 在元件中注入 HttpClient
private httpClient = inject(HttpClient);

若要在使用模組時提供 HttpClient,則需要在根模組中加入 provideHttpClientproviders 陣列中

@NgModule({
  ...
  providers: [provideHttpClient()],
  bootstrap: [AppComponent],
})
export class AppModule {}

發送 HTTP 請求

HttpClient 有提供多種方法來發送 HTTP 請求,像是常見的 GET、POST、PUT、DELETE 等。

this.httpClient.get('localhost:3000/tasks')
this.httpClient.post('localhost:3000/tasks', { name: 'New Task' })

由於 HttpClient 的方法會回傳 Observable ,可以使用 RxJS 來處理非同步資料流

this.httpClient.get('http://localhost:3000/tasks').subscribe({
	  next: (resData) => {
		  console.log(resData);
	  },
	  error: (err) => {
		  console.error(err);
		},
		complete: () => {
		  console.log('Completed');
		}
});

可搭配 destroyRef 來取消訂閱 Observable。

destroyRef 用於管理元件的生命週期,在元件銷毀時自動清理資源

private destroyRef = inject(DestroyRef);

ngOnInit() {
 const subscription = this.httpClient ...
	 
 this.destroyRef.onDestroy(() => {
		this.subscription.unsubscribe();
	});
}

HttpClient 的方法也可以設定回傳的資料型別

this.httpClient.get<{ tasks: Tasks[] }>('http://localhost:3000/tasks')

HTTP 攔截器 HTTP Interceptors

攔截器是一種特殊的服務,可以攔截並修改 HTTP 請求和回應,做出一些額外的處理,例如:記錄請求資訊、錯誤處理等。
目前推薦使用函式方式來定義攔截器,這樣可以避免建立多餘的類別。

provideHttpClient 中使用 withInterceptors 來註冊攔截器,將設定好的攔截器函式傳入陣列中。

function loggingInterceptor(request: HttpRequest<unknown>, next: HttpHandlerFn){
  return next(request).pipe(
     tap({
			next: (event) => {
				if(event.type === HttpEventType.Response) {
					console.log('Response received:', event);
				}
			},
		})
  )
}

bootstrapApplication(AppComponent, {
	  providers: [
	    provideHttpClient({
	      withInterceptors([loggingInterceptor]
	    }),
	  ],
})

除了函式方式,也可以使用類別方式來定義攔截器,這種方式較少使用。

@Injectable()
export class LoggingInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request).pipe(
      tap({
        next: (event) => {
          if (event.type === HttpEventType.Response) {
            console.log('Response received:', event);
          }
        },
      })
    );
  }
}

用這種類別方式定義的攔截器,註冊方式也不同,要用 withInterceptorsFromDi() 啟用攔截器
並在 providers 陣列中加入自訂的攔截器 provider。

  • provide: 設定為 HTTP_INTERCEPTORS,這是 Angular 提供的 token,用來標識 HTTP 攔截器。
  • useClass:指定要使用的攔截器類別。
  • multi: true:表示這個 provider 可以有多個攔截器。

如果你有多個類別 HTTP 攔截器,按順序加入 providers 陣列中即可。


  providers: [
    provideBrowserGlobalErrorListeners(),
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(withInterceptorsFromDi()), // 讓 DI 攔截器生效
    { provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true }
  ]

結論

今天介紹了如何在 Angular 中使用 HttpClient 來發送 HTTP 請求,並處理回應資料。明天會介紹路由相關的內容。


上一篇
Day 24 - RxJs
下一篇
Day 26 - Routing (一)
系列文
Angular 新手練功日誌:從零到職場冒險26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言